<template>
    <div :class="{[prefixCls+'-dropdown']:true,[prefixCls+'-dropdown-active']:isActive}" @mouseenter="trigger === 'hover'?enter():false" @mouseleave="trigger === 'hover'?out():false">
        <div :class="[prefixCls+'-dropdown-link']" @click="handleClick" ref="link">
            <slot></slot>
        </div>
        <transition name="slide" v-if="show">
            <div :class="[prefixCls+'-dropdown-menu']" ref="dropdown">
                <slot name="list"></slot>
            </div>
        </transition>
    </div>
</template>

<script>
import { prefixCls } from '../prefix'
import Vue from 'vue'
import newDrop from './new'

export default {
    name: `${prefixCls}Dropdown`,
    props: {
        trigger: {
            type: String,
            default: 'hover',
        },
        placement: {
            type: String,
            default: 'center',
        },
        transfer:{
        	type:Boolean,
        	default:false
        }
    },
    components:{ newDrop },
    data() {
        return {
            prefixCls: prefixCls,
            isActive: false, //下拉层激活状态
            clearTime: {
                down: '',
                up: '',
                t:''
            },
            delay: 300, //下拉层延迟展开时间，hover方式使用
            dropDownData:'',//下拉层数据
            show:true,//挂载到body的，隐藏原位置下拉层
            newDropDown:'',//动态下拉层内容
            isNewShow:false,//动态下拉层是否显示中，只用于hover

        }
    },
    mounted() {
    	// console.log( this)
        //下拉层延迟展开时间，click方式去掉延迟时间
        if (this.trigger === "click") {
            this.delay = 0
        }
        document.addEventListener('click', this.hideDropdown, false)
        // 滚动条的获取
        window.addEventListener('scroll', this.handleScroll, true)

        // 得到slot下拉层中的数据，再把slot隐藏，挂载到body中
        if(this.transfer){
    		this.dropDownData = this.$slots.list[0].elm.children;
    		this.show = false;
        }else{
        	this.show = true;
        }
    },
    provide() {
        return {
            parentClick: this.parentClick,
            dropDownSlideUp: this.out,
        }
    },
    methods: {
        /** 
         * 点击空白处，隐藏下拉层
         * e1：触发link结构
         * e2：下拉层展开时的结构，但获取不到动态生成的下拉层
         * e3：动态组件下拉层结构
         */
        hideDropdown(e) {
        	if(this.isActive){
	            let e1 = this.$refs.link.contains(e.target);
	            let e2 = this.$refs.dropdown?this.$refs.dropdown.contains(e.target):'';
	            let e3 = this.newDropDown?this.newDropDown.$el.contains(e.target):'';
	            if (!e1 && !e2 && !e3) {
	                this.out()
	            }
        	}
        },
        // 展开
        enter() {
        	const _this = this;
            if(_this.transfer){
            	// 动态生成在body的下拉层
            	if(_this.newDropDown){
            		// _this.out()
            	}else{
            		_this.clearTime.down = setTimeout(() => {
	            		_this.createDropDown()
	            		const _dp = _this.newDropDown.$el;
	            		_this.setDropDownPosition(_dp);
	            		_this.isActive = true

	            		// 当动态组件使用hover，绑定mouse事件
	            		if (_this.trigger === "hover") {
	            			_this.isNewShow = true
		            		_dp.addEventListener('mouseover', function(e){
		            			clearTimeout(_this.clearTime.t)
		            		}, false)
		            		_dp.addEventListener('mouseleave', function(e){
		            			_this.isNewShow = false
		            			// if(_this.isNewShow){
	            					_this.out()
		            			// }
		            		}, false)
	            		}
            		},_this.delay)	
            	}
            }else{
	        	// 原始结构中下拉层
	            const _dp = _this.$refs.dropdown;
	            clearTimeout(_this.clearTime.up)
	            _this.clearTime.down = setTimeout(() => {
	                _dp.classList.add('slide-down')
	                _dp.classList.remove('slide-up')
	                _this.setDropDownPosition(_dp);
	                _this.isActive = true
	            }, _this.delay)
            }
        },
        // 收起
        out() {
        	const _this = this;
        	if(_this.isNewShow){
        		_this.clearTime.t = setTimeout(()=>{
        			_this.isNewShow = false
        			_this.out()
        		},100)
        		return false;
        	}

        	// 动态生成在body的下拉层
        	if(this.newDropDown) {
        		let newDom = this.newDropDown;
		    	const dp = this.newDropDown.$el;
		    	// console.log('动态生成在body的下拉层',dp)
        		
		     	// 销毁组件
			    if(newDom){
	                dp.classList.remove('slide-down')
	                dp.classList.add('slide-up')
	                _this.isActive = false
	                _this.clearTime.up = setTimeout(() => {
	                    dp.classList.remove('slide-up')
	                    dp.removeAttribute("style")
	                    dp.removeAttribute("position")
				    	dp.parentNode?dp.parentNode.removeChild(dp):''
				    	newDom.$destroy()
				    	this.newDropDown = ''
	                }, 300)
			    }
        	}

        	// 原始结构中下拉层
            const _dp = _this.$refs.dropdown;
            clearTimeout(_this.clearTime.down)
            if (_this.isActive) {
                _dp.classList.remove('slide-down')
                _dp.classList.add('slide-up')
                _this.isActive = false
                _this.clearTime.up = setTimeout(() => {
                    _dp.classList.remove('slide-up')
                    _dp.removeAttribute("style")
                    _dp.removeAttribute("position")
                }, 300)
            }
        },
        // 点击展开下拉层,trigger="click"
        handleClick() {
            if (this.trigger === "click") {
                if (this.isActive) {
                    this.out()
                } else {
                    this.enter()
                }
            }
        },
        // 触发最外层的事件
        parentClick(name, value) {
            this.$emit('click', name, value)
        },
        // 设置下拉层位置
        setDropDownPosition(dp) {
            const DOMRect1 = this.$refs.link.getBoundingClientRect(),
                  DOMRect2 = dp.getBoundingClientRect();

            const _l1 = DOMRect1.left,
            	  _t1 = DOMRect1.top,
                  _w1 = DOMRect1.width,
                  _w2 = DOMRect2.width,
                  _h1 = DOMRect1.height,
                  _h2 = dp.offsetHeight, //下拉层高度,这个算出来准
                  _t2 = DOMRect2.top,
                  _st = window.pageYOffset, //滚动高度
                  _ch = document.documentElement.clientHeight; //浏览器可视化窗口的大小  

            // console.log('下拉层link：',DOMRect1)
            // console.log('下拉层1：',DOMRect2)
            // console.log('下拉层2：',dp.offsetHeight)
            // console.log('滚动',_st)
            // console.log(_h1 + _t1 + _h2)

            // 自动识别窗口高度，底部高度不足，下拉层往上展开
        	// 动态生成在body的下拉层
        	if(this.newDropDown) {
        		if (Number(_t1+_h1+_h2+5) > _ch) {
        			dp.setAttribute('position', 'top');
        			dp.style.top = (_t1-_h2+_st-5)+'px';
        			dp.style.left = _l1+'px';
        		}else{
        			dp.style.top = (_t1+_h1+_st)+'px';
        			dp.style.left = _l1+'px';
        		}
        	}else{
	            // 原始结构中下拉层
	            let _mt;
	            if (_t2 > _st) {
	                if ((_t2 + _h2) > _ch) {
	                    dp.setAttribute('position', 'top');
	                    _mt = '-' + (_h1 + _h2 + 5).toFixed(2);
	                    dp.style.marginTop = _mt + 'px'
	                }
	            }
        	}

            // 组件水平位置，通过参数'placement'设置
            let _ml;
            switch (this.placement) {
                case 'left':
                    break;
                case 'right':
                    if (_w2 >= _w1) {
                        _ml = '-' + (_w2 - _w1).toFixed(2);
                    } else {
                        _ml = (_w1 - _w2).toFixed(2);
                    }
                    dp.style.marginLeft = _ml + 'px'
                    break;
                case 'center':
                    if (_w2 >= _w1) {
                        _ml = '-' + ((_w2 - _w1) / 2).toFixed(2);
                    } else {
                        _ml = ((_w1 - _w2) / 2).toFixed(2);
                    }
                    dp.style.marginLeft = _ml + 'px'
                    break;
            }
        },
        // 指定目标创建下拉层
        createDropDown() {
            const n = this.create(newDrop,{
            	content: this.dropDownData
            })
            this.newDropDown = n;
        },
        create(Component,props){
			  // 1. 构建Component的实例
			  const vm = new Vue({
			    render: (h) => {
			      return h(Component, {props})
			    }
			    // 不能直接挂载在body节点上,因为$mount()是覆盖性操作.
			  }).$mount()
			  
			  // 2.将真实节点挂载到body上，vm.$el是实例的真实节点。
			  document.body.appendChild(vm.$el)

			  // 3.获取组件实例
			  const comp = vm.$children[0]

			  comp.remove = () => {
			    document.body.remove(vm.$el)
			    vm.$destroy()
			  }
			  return comp
        },
        handleScroll() {
            // console.log('滚动高度', window.pageYOffset)
            // console.log('距离顶部高度', this.$refs.link.getBoundingClientRect().top)
        },
    },

}
</script>
